/**
 * 单元名称：图片处理方法
 * 单元功能：对图片进行压缩、添加水印
 * 所属模块功能：
 * 创建人：yan
 * 创建时间：230823
 * 修改人：
 * 修改时间：
 */


/**
 * 图片文件压缩
 * @param file 图片文件
 * @param opts 添加文字水印参数
 * @description
 *  1、将文件转img对象
 *  2、获取文件宽高比例
 *  3、自定义等比例缩放宽高属性，这里我用的是固定800宽度，高度是等比例缩放
 *  4、判断是否有opts添加文字水印参数，有则调用添加文字水印方法
 *  5、canvas重新绘制图片
 *  6、canvas转二进制对象转文件对象，返回
 *
 * @return {Promise<*>}
 */
export const imgCompress_v1 = async (file, opts, _this) => {
  const img = await file2Img(file);
  return new Promise((resolve, reject) => {
    // const canvas = document.createElement('canvas'),
    const query = wx.createSelectorQuery().in(_this);
    query.select('#mycanvas').fields({
      node: true,
      size: true
    })
      .exec(res => {
        const canvas = res[0].node
        const ctx = canvas.getContext('2d');
        //  获取文件宽高比例
        const { width: originWidth, height: originHeight } = img;
        canvas.width = originWidth
        canvas.height = originHeight;
        _this.setData({
          canvasStyle: `width: ${originWidth}rpx;height: ${originHeight}rpx;`
        })
        const image = canvas.createImage()
        image.src = file.tempFilePath
        image.onload = function () {
          debugger
          let dpr = wx.getSystemInfoSync().pixelRatio;
          //  自定义等比例缩放宽高属性， 固定面积220000，宽度高度等比例缩放
          const scale = +(originWidth / originHeight).toFixed(2) //比例取小数点后两位
          const s = 500000,
            root = Math.sqrt(s / (originWidth * originHeight)),  //指定大小除以当前大小开根号
            targetWidth = Math.round(root * originWidth),
            targetHeight = Math.round(root * originHeight),
            width = targetWidth * dpr,  //按设备像素放大
            height = targetHeight * dpr;//按设备像素放大


          // ctx.clearRect(0, 0, width, height)
          // canvas重新绘制图片
          ctx.drawImage(image, 0, 0, originWidth, originHeight)

          // ctx.scale(dpr,dpr)

          if (opts) {
            fillText(ctx, opts, originWidth, originHeight);
          }
          // canvas转二进制对象转文件对象，返回
          setTimeout(() => {
            wx.canvasToTempFilePath({
              canvas: canvas,
              // destWidth: targetWidth, //目标宽度
              // destHeight: targetHeight, //目标高度
              fileType: 'jpg',
              // quality: 0.8, // 图片质量 0-1
              success: (res) => {
                // file.path = res.tempFilePath;
                resolve(res)
              },
              fail (err) {
              }
            }, _this)
          }, 600)
        }
      })

  })
}

/*新压缩图片，先添加水印，再用微信api压缩*/
let systemInfo = null;
export const imgCompress = async (file, opts, _this) => {
  let filePath = file.tempFilePath
  const size = file.size / 1024 / 1024;
  console.log('sizeBefore', size);
  const img = await file2Img(file);
  return new Promise((resolve, reject) => {
    const query = wx.createSelectorQuery().in(_this);
    query.select('#mycanvas').fields({
      node: true,
      size: true
    })
      .exec(res => {
        const canvas = res[0].node
        const ctx = canvas.getContext('2d');
        const image = canvas.createImage()
        image.src = filePath
        image.onload = function () {
          systemInfo = wx.getSystemInfoSync();
          // let dpr = systemInfo.pixelRatio;
          //  获取文件宽高比例
          const { width, height } = img;

          _this.setData({
            canvasStyle: `width: ${width}rpx;height: ${height}rpx;`
          })

          canvas.width = width
          canvas.height = height

          ctx.clearRect(0, 0, width, height)
          // canvas重新绘制图片
          ctx.drawImage(image, 0, 0, width, height)

          if (opts) {
            fillText(ctx, opts, width, height);
          }
          // canvas转二进制对象转文件对象，返回
          setTimeout(() => {
            wx.canvasToTempFilePath({
              canvas: canvas,
              // destWidth: width, //目标宽度
              // destHeight: height, //目标高度
              fileType: 'jpg',
              // quality: 0.8, // 图片质量 0-1
              success: (res) => {
                // file.path = res.tempFilePath;
                // resolve(res)
                wx.getFileSystemManager().getFileInfo({
                  filePath: res.tempFilePath,
                  success: async fileInfo => {
                    console.log('添加水印后', fileInfo.size / 1024 / 1024)
                    // 手动压缩
                    let filePath = await compressImage(res.tempFilePath, fileInfo.size)
                    resolve(filePath)
                    wx.getFileSystemManager().getFileInfo({
                      filePath: filePath.tempFilePath,
                      success: fileInfo => {
                        console.log(fileInfo);
                        console.log('微信压缩后', fileInfo.size / 1024 / 1024)
                      },
                      fail: err => {
                        console.error('获取压缩后图片信息失败:', err);
                      }
                    });
                  },
                  fail: err => {
                    console.error('获取压缩后图片信息失败:', err);
                  }
                });

              },
              fail (err) {
              }
            }, _this)
          }, 600)
        }
      })

  })
}
const compressFile = (src, size) => {
  let that = this
  return new Promise((resolve) => {
    // 获取图片信息
    wx.getImageInfo({
      src,
      success: (img) => {
        let imgWidth = img.width
        let imgHeight = img.height
        //这段必看！！！！
        /*const windowWidth= wx.getSystemInfoSync().windowWidth;
        let imgRatio = imgHeight/imgWidth;
        that.setData({
          compressH: windowWidth * imgRatio
        })*/
        compressImage(src, size).then(res => {
          resolve(res)
        })
      },
      fail: () => {
        compressImage(src, size).then(res => {
          resolve(res)
        })
      }
    })
  })
}
const compressImage = (src, size) => {
  let that = this
  return new Promise((resolve, reject) => {
    /*let quality = 100
    // ios因为自己有压缩机制，压缩到极致就不会再压，因此往小了写
    if (systemInfo?.platform?.toLowerCase() === 'ios') {
      quality = 0.1
    } else {
      let temp = 30 - parseInt(size / 1024 / 1024)
      quality = temp < 10 ? 10 : temp
    }*/
    wx.compressImage({
      src, // 图片路径
      quality: 100, // 压缩质量
      success: function (res) {
        console.log('官方API压缩res', res,)
        //
        resolve(res)
      },
      fail: function (err) {
        resolve(src)
      }
    })
  })
}


/**
 * 图片file转化成img对象
 * @param file
 * @return {Promise<any>}
 */
export const file2Img = (file) => {
  return new Promise((resolve, reject) => {
    /*const img = new Image(),
      reader = new FileReader();
    reader.onload = e => img.src = e.target.result;
    reader.onerror = e => reject(e);
    reader.readAsDataURL(file);
    img.onload = () => resolve(img);
    img.onerror = (e) => reject(e);*/
    wx.getImageInfo({
      src: file.tempFilePath,
      success (res) {
        resolve(res)
      }
    })
  })
}

/**
 * 图片添加水印
 * @param file 图片文件
 * @param opts 添加文字水印参数
 * @description 没有进行压缩处理的图片直接添加水印
 * @return {Promise<*>}
 */
export const addWatermark = async (file, opts) => {
  const img = await file2Img(file);
  return new Promise((resolve, reject) => {
    const canvas = document.createElement('canvas'),
      context = canvas.getContext('2d');
    //  获取文件宽高比例
    const { width: originWidth, height: originHeight } = img;
    canvas.width = originWidth
    canvas.height = originHeight;

    context.clearRect(0, 0, originWidth, originHeight)
    // canvas重新绘制图片
    context.drawImage(img, 0, 0, originWidth, originHeight)

    fillText(context, opts, originWidth, originHeight);

    // canvas转二进制对象转文件对象，返回
    const type = 'image/png'
    canvas.toBlob(blob => {
      const f = new File([blob], file.name, {
        type,
        lastModified: file.lastModified
      })
      resolve(f)
    }, type)
  })
}

/**
 * 画布画文字
 * @param ctx canvas上下文
 * @param opts {Array} 定义文字参数数组
 * opts: {
 *   textAlign: // 水印文字的对齐方式
 *   font: "16px Microsoft Yahei", // 水印文字的字体
 *   textBaseline: "middle", // 水印文字的基线
 *   fillStyle: "rgba(184, 184, 184, 0.6)", // 水印文字的填充样式
 *   content: '名称', // 水印文字的内容
 *   rotate: -30, // 水印文字的旋转角度
 *   zIndex: 10000, // 水印的 z-index 值
 *   position: {
 *     top: 0,
 *     left: 0,
 *     right: 0,
 *     bottom: 0
 *   }
 *   top: '',   //水印位置top
 *   left: '',  //水印位置right
 * }
 * @param width 画布宽度
 * @param height 画布高度
 */
const fillText = (ctx, opts, width, height) => {
  for (let i = 0; i < opts.length; i++) {
    let item = opts[i];
    console.log(item);
    let { content, textAlign, font, lineWidth, textBaseline, fillStyle, rotate, zIndex, position } = item;
    console.log(font);
    textAlign && (ctx.textAlign = textAlign);
    textBaseline && (ctx.textBaseline = textBaseline);
    ctx.font = font || '16px serif';
    console.log(ctx.font);
    ctx.fillStyle = fillStyle || '#ffffff';
    rotate && ctx.rotate((Math.PI / 180) * rotate);
    let x = 0, y = 0,
      metrics = ctx.measureText(content),
      textWidth = metrics.width,
      textHeight = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;

    if (position) {
      let { left, top, bottom, right } = position;
      //计算文字位置
      x = right ? width - right - textWidth : 0;
      x = left ? left : x;  //left 优先于 right
      x = x > width ? width - textWidth : x;  //超出画布宽度
      x = x < 0 ? 0 : x;  //小于画布

      y = bottom ? height - bottom : 0;
      y = top ? top + textHeight : y;  //top 优先于 bottom
      y = y > height ? height : y < 0 ? 0 : y;  //超出画布宽度
    }

    //空心描边
    ctx.lineWidth = lineWidth || 2;
    ctx.strokeStyle = '#000';
    ctx.strokeText(content, x, y);

    ctx.fillText(content, x, y);// 绘制文字，实心填充

  }
  /*opts.forEach(item => {
    let {content,textAlign,font ,textBaseline ,fillStyle ,rotate ,zIndex,position } = item;
    textAlign && (ctx.textAlign = textAlign);
    textBaseline && (ctx.textBaseline = textBaseline);
    ctx.font = font || '16px serif';
    ctx.fillStyle = fillStyle || '#ffffff';
    rotate && ctx.rotate((Math.PI / 180) * rotate);
    let x = 0,y = 0,
      metrics = ctx.measureText(content),
      textWidth = metrics.width,
      textHeight = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;

    if (position){
      let {left, top, bottom, right} = position;
      //计算文字位置
      x = right ? width - right - textWidth : 0;
      x = left ? left : x;  //left 优先于 right
      x = x > width ? width - textWidth : x;  //超出画布宽度
      x = x < 0 ? 0 : x;  //小于画布

      y = bottom ? height - bottom : 0;
      y = top ? top + textHeight : y;  //top 优先于 bottom
      y = y > height ? height : y < 0 ? 0 : y;  //超出画布宽度
    }
    //空心描边
    ctx.lineWidth = 2;
    ctx.strokeStyle = '#000';
    ctx.strokeText(content, x, y);

    ctx.fillText(content,x,y);// 绘制文字，实心填充

  })*/
}

//canvas文本过长 自动换行
function drawText (ctx, str, leftWidth, initHeight, titleHeight, canvasWidth) {

  var lineWidth = 0;
  var lastSubStrIndex = 0; //每次开始截取的字符串的索引
  for (let i = 0; i < str.length; i++) {
    lineWidth += ctx.measureText(str[i]).width;
    if (lineWidth > canvasWidth) {
      ctx.fillText(str.substring(lastSubStrIndex, i), leftWidth, initHeight); //绘制截取部分
      initHeight += 16; //16为字体的高度
      lineWidth = 0;
      lastSubStrIndex = i;
      titleHeight += 30;
    }
    if (i == str.length - 1) { //绘制剩余部分
      ctx.fillText(str.substring(lastSubStrIndex, i + 1), leftWidth, initHeight);
    }
  }
  // 标题border-bottom 线距顶部距离
  titleHeight = titleHeight + 10;
  return titleHeight
}


export const imgCompressSec = async (file, opts, _this) => {
  let filePath = file.tempFilePath
  const size = file.size / 1024 / 1024;
  console.log('sizeBefore', size);
  const img = await file2Img(file);
  return new Promise((resolve, reject) => {
    const query = wx.createSelectorQuery();
    query.select('#mycanvas').fields({
      node: true,
      size: true
    })
      .exec(res => {
        const canvas = res[0].node
        const ctx = canvas.getContext('2d');
        const image = canvas.createImage()
        image.src = filePath
        image.onload = function () {
          systemInfo = wx.getSystemInfoSync();
          // let dpr = systemInfo.pixelRatio;
          //  获取文件宽高比例
          const { width, height } = img;

          _this.setData({
            canvasStyle: `width: ${width}rpx;height: ${height}rpx;`
          })

          canvas.width = width
          canvas.height = height

          ctx.clearRect(0, 0, width, height)
          // canvas重新绘制图片
          ctx.drawImage(image, 0, 0, width, height)

          if (opts) {
            fillText(ctx, opts, width, height);
          }
          // canvas转二进制对象转文件对象，返回
          setTimeout(() => {
            wx.canvasToTempFilePath({
              canvas: canvas,
              // destWidth: width, //目标宽度
              // destHeight: height, //目标高度
              fileType: 'jpg',
              // quality: 0.8, // 图片质量 0-1
              success: (res) => {
                // file.path = res.tempFilePath;
                // resolve(res)
                wx.getFileSystemManager().getFileInfo({
                  filePath: res.tempFilePath,
                  success: async fileInfo => {
                    console.log('添加水印后', fileInfo.size / 1024 / 1024)
                    // 手动压缩
                    let filePath = await compressImage(res.tempFilePath, fileInfo.size)
                    resolve(filePath)
                    wx.getFileSystemManager().getFileInfo({
                      filePath: filePath.tempFilePath,
                      success: fileInfo => {
                        console.log(fileInfo);
                        console.log('微信压缩后', fileInfo.size / 1024 / 1024)
                      },
                      fail: err => {
                        console.error('获取压缩后图片信息失败:', err);
                      }
                    });
                  },
                  fail: err => {
                    console.error('获取压缩后图片信息失败:', err);
                  }
                });

              },
              fail (err) {
              }
            }, _this)
          }, 600)
        }
      })

  })
}


